package com.simpligility.maven.plugins.android; import com.android.ddmlib.IDevice; import com.android.ddmlib.testrunner.ITestRunListener; import com.android.ddmlib.testrunner.TestIdentifier; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; import org.apache.maven.plugin.logging.SystemStreamLog; import org.easymock.EasyMockRunner; import org.easymock.Mock; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.xml.sax.SAXException; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import java.io.File; import java.io.IOException; import java.util.Collections; import static org.easymock.EasyMock.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(EasyMockRunner.class) public class AndroidTestRunListenerTest { @Mock private IDevice device; private final String suffix = RandomStringUtils.randomAlphabetic( 10 ); private final String serial = RandomStringUtils.randomAlphabetic( 10 ); private final String avd = RandomStringUtils.randomAlphabetic( 10 ); private final String manufacturer = RandomStringUtils.randomAlphabetic( 10 ); private final String model = RandomStringUtils.randomAlphabetic( 10 ); private final String runName = RandomStringUtils.randomAlphabetic( 10 ); private final String key = RandomStringUtils.randomAlphabetic( 10 ); private final String value = RandomStringUtils.randomAlphabetic( 10 ); private final int count = RandomUtils.nextInt( 1, 10 ); private final int elapsed = RandomUtils.nextInt( 10, 1000 ); @Rule public TemporaryFolder target = new TemporaryFolder(); @Before public void setUp() throws Exception { expect( device.getSerialNumber() ).andReturn( serial ).anyTimes(); expect( device.getAvdName() ).andReturn( avd ).anyTimes(); expect( device.getProperty( "ro.product.manufacturer" ) ).andReturn( manufacturer ).anyTimes(); expect( device.getProperty( "ro.product.model" ) ).andReturn( model ).anyTimes(); expect( device.getProperties() ).andReturn( Collections.singletonMap( key, value ) ).anyTimes(); } private String randomTrace() { return RandomStringUtils.randomAlphabetic( 20 ) + ":" + RandomStringUtils.randomAlphabetic( 20 ); } @Test public void validReport() { replay( device ); final ITestRunListener listener = new AndroidTestRunListener( device, new SystemStreamLog(), true, false, null, suffix, target.getRoot() ); listener.testRunStarted( runName, count ); final int tests = RandomUtils.nextInt( 5, 10 ); for (int i = 0; i < tests; i++) { final TestIdentifier id = new TestIdentifier( RandomStringUtils.randomAlphabetic( 20 ), RandomStringUtils.randomAlphabetic( 10 ) ); listener.testStarted( id ); switch (RandomUtils.nextInt( 0, 4 )) { case 0: listener.testFailed( id, randomTrace()); break; case 1: listener.testAssumptionFailure( id, randomTrace() ); break; case 2: listener.testIgnored( id ); } listener.testEnded( id, Collections.<String, String>emptyMap() ); } if (RandomUtils.nextInt( 0, 1 ) == 1) { listener.testRunFailed( RandomStringUtils.randomAlphabetic( 20 ) ); } listener.testRunEnded( elapsed, Collections.<String, String>emptyMap() ); verify( device ); assertEquals( 1, target.getRoot().listFiles().length ); assertEquals( 1, target.getRoot().listFiles()[0].listFiles().length ); for (File file : target.getRoot().listFiles()[0].listFiles()) { assertTrue( validateXMLSchema( "surefire/surefire-test-report.xsd", file ) ); } } public boolean validateXMLSchema( String xsdResource, File xmlFile ) { try { final SchemaFactory factory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI ); final Schema schema = factory.newSchema( new StreamSource( getClass().getClassLoader().getResourceAsStream( xsdResource ) ) ); final Validator validator = schema.newValidator(); validator.validate( new StreamSource( xmlFile ) ); } catch (IOException | SAXException e) { e.printStackTrace(); return false; } return true; } }